import { GridCellEditWrapper } from '@/components/form';
import { BaseSelect } from '@/components/form/loupeselect';
import { GroupColumn } from '@/components/popovercolumn';
import { getOtherTreeOrgAPI, getOtherTreeOrgByAuthAPI } from '@/services/selectors';
import exporter from '@/utils/cache';
import { getOrganizationField, getOrganizationInfo } from '@/utils/organization';
import { formatTreeData } from '@/utils/utils';
import { isEmpty, cloneDeep } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { connect } from 'umi';
import { renderlinkEle } from '../utils';
import SelectorModal from './SelectorModal';
import { nameKeys } from './static';
import { getShowDataSource, recursionTreeData } from './utils';
import { getLocale } from 'umi';
import { LOCALE_MAP } from '@/utils/utils';

const locale = getLocale();
const systemLocale = LOCALE_MAP[locale];
const { selector: selectorCache }: { selector?: any } = exporter;
const { dropDownEleKey, popoverEleKey } = nameKeys;

export interface ReadElementProps {
  value: string | string[];
  showMode?: 'popover' | 'link' | 'custom' | 'simple' | 'mixed';
  linkTo?: string | Function | object;
  customShow?: (text: string, record: any) => any;
}

export interface SelectorFormItemProps extends ReadElementProps {
  excludeId?: string;
  multiple?: boolean;
  onChange?: (selectedRowKeys: string[], selectedRows: object[]) => void;
  onCancel?: () => void;
  onOk?: (selectedRowKeys: string[], selectedRows: object[]) => void;
}

const SelectorFormItem = (props: any) => {
  const {
    excludeId,
    treeOrganizations,
    treeOrganizationsByAuth,
    value,
    autoFocus,
    onBlur,
    onChange,
    multiple,
    addonAfter,
    dispatch,
    withAuth,
    showMode,
    linkTo,
    customShow,
    disabledByLevel = false,
    ...restProps
  } = props;

  const [visible, setVisible] = useState(false);
  const [filterData, setFilterData] = useState([]);

  // grid 列表中使用，管理编辑和展示状态
  const [selectFocus, setSelectFocus] = useState(false);
  const [dropdownVisible, setDropdownVisible] = useState(false);

  const getCurrentTitleField = (field: string, enField: string = 'orgNameEn') => {
    return systemLocale === 'en' ? enField : field;
  };

  const initFetch = useCallback(() => {
    if (excludeId) return;
    if ((withAuth && treeOrganizationsByAuth.length) || (!withAuth && treeOrganizations.length)) return;
    dispatch({ type: 'selectors/fetchTreeOrg', payload: { withAuth } });
  }, [treeOrganizations, excludeId, withAuth]);

  const handlerChange = useCallback(
    (selectedRowKeys: string[]) => {
      const ret: any = multiple ? selectedRowKeys : selectedRowKeys[0];
      onChange && onChange(ret);
      setVisible(false);
      setSelectFocus(false);
      setDropdownVisible(false);
    },
    [multiple],
  );

  const getExcludeData = useCallback(async () => {
    const key = `groupSelector_${withAuth ? 'auth' : 'all'}:${excludeId}`;
    let cacheData = selectorCache.get(key);
    if (!cacheData) {
      try {
        const api = (withAuth && getOtherTreeOrgByAuthAPI) || getOtherTreeOrgAPI;
        const res = await api({ data: { id: excludeId, node: 'root', pageInfo: {} }, serviceId: 'fwSecurity' });
        formatTreeData(res, 'children', { title: 'orgName', titleEn: 'orgNameEn' });
        selectorCache.set(key, res);
        cacheData = res;
      } catch (err) {
        console.error(err);
      }
    }
    setFilterData(cacheData);
  }, [excludeId, withAuth]);

  //选择改变
  const handlerSelectorChange = (id: any, rows: any[]) => {
    onChange && onChange(id, rows);
    setSelectFocus(false);
    setDropdownVisible(false);
  };

  const renderReadElement = useCallback(() => {
    if (showMode === 'custom') {
      const orgInfo = getOrganizationInfo(value);
      return customShow && customShow(value, orgInfo);
    }
    if (Array.isArray(value)) {
      return value
        .map((id) => getOrganizationField({ id, field: getCurrentTitleField('fullOrgName') }) || id)
        .join('、');
    }
    if (!value) return;
    const name = getOrganizationField({ id: value, field: getCurrentTitleField('fullOrgName') });
    const record = getOrganizationInfo(value);
    if (isEmpty(record)) return value;

    switch (showMode) {
      case 'popover':
        return <GroupColumn data={record} />;
      case 'link':
        return renderlinkEle(value, name, linkTo);
      case 'mixed':
        return (
          <GroupColumn trigger="hover" data={record} overlayClassName={popoverEleKey}>
            {renderlinkEle(value, name, linkTo)}
          </GroupColumn>
        );
      default:
        return name;
    }
  }, [value, showMode, linkTo, customShow]);

  const treeData = useMemo(() => {
    if (excludeId) return filterData;
    return getShowDataSource(withAuth ? treeOrganizationsByAuth : treeOrganizations);
  }, [excludeId, withAuth, filterData, treeOrganizations, treeOrganizationsByAuth]);

  const disabledTreeData = useMemo(() => {
    const data = cloneDeep(treeData);
    if (disabledByLevel) {
      recursionTreeData(data);
    }

    return data;
  }, [treeData, disabledByLevel]);

  //下拉时
  const onDropdownVisibleChange = (open: boolean) => {
    setDropdownVisible(open);
  };

  useEffect(() => {
    initFetch();
  }, []);

  useEffect(() => {
    excludeId && getExcludeData();
  }, [excludeId]);

  return (
    <>
      <GridCellEditWrapper autoFocus={autoFocus} onBlur={onBlur} visible={visible || selectFocus || dropdownVisible}>
        <BaseSelect
          value={value}
          dropdownClassName={dropDownEleKey}
          dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
          treeData={disabledTreeData}
          onChange={handlerSelectorChange}
          showSearch
          multiple={multiple}
          onFocus={() => setSelectFocus(true)}
          onBlur={() => setSelectFocus(false)}
          treeNodeFilterProp={getCurrentTitleField('orgName')}
          componentType="TreeSelect"
          onLoupeClick={() => setVisible(true)}
          renderReadElement={renderReadElement}
          onDropdownVisibleChange={onDropdownVisibleChange}
          {...restProps}
        />
        <SelectorModal
          excludeId={excludeId}
          multiple={multiple}
          value={multiple ? value : value && [value]}
          onCancel={() => setVisible(false)}
          onOk={handlerChange}
          visible={visible}
          withAuth={withAuth}
        />
      </GridCellEditWrapper>
    </>
  );
};

SelectorFormItem.defaultProps = {
  multiple: false,
  showMode: 'simple',
  withAuth: false,
};

SelectorFormItem.setDefaultProps = (defaultProps: SelectorFormItemProps) => {
  Object.assign(SelectorFormItem.defaultProps, defaultProps);
};

export default connect(({ selectors }: { selectors: any }) => ({
  treeOrganizations: selectors.treeOrganizations,
  treeOrganizationsByAuth: selectors.treeOrganizationsByAuth,
}))(SelectorFormItem);
